package com.erp.auto.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.erp.auto.domain.ErpAutoPulishProductProject;
import com.erp.auto.domain.ErpAutoUnshelfProductConfig;
import com.erp.auto.domain.ErpAutoUnshelfProductLog;
import com.erp.auto.mapper.*;
import com.erp.auto.service.ErpAutoUnshelfProductConfigService;
import com.erp.auto.service.IErpAutoPublishProductProjectService;
import com.ruoyi.ae.api.RemoteAeProductService;
import com.erp.auto.service.IErpAutoPulishProductProjectTaskService;
import com.ruoyi.gather.api.RemoteGatherProductService;
import com.ruoyi.statistics.api.RemoteOrderStatisticsService;
import com.ruoyi.statistics.api.domain.ErpChildOrderStatistics;
import com.ruoyi.auto.api.domain.ErpAutoPulishProductProjectTask;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.gather.api.RemoteSellerStoreCommodityRankStatisticsService;
import com.ruoyi.gather.api.RemoteSellerStoreProductService;
import com.ruoyi.gather.api.domain.ErpSellerStoreProduct;
import com.ruoyi.gather.api.domain.ErpSellerStoreProductExpand;
import com.ruoyi.shop.api.RemoteSellerStoreService;
import com.ruoyi.shop.api.domain.ErpSellerStoreEmpower;
import com.ruoyi.statistics.api.RemoteOrderStatisticsService;
import com.ruoyi.statistics.api.domain.ErpChildOrderStatistics;
import lombok.AllArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 下架商品配置表
 *
 * @author WXX
 * @date 2024-01-16 10:04:56
 */
@Service
@AllArgsConstructor
public class ErpAutoUnshelfProductConfigServiceImpl implements ErpAutoUnshelfProductConfigService {

    private final ErpAutoUnshelfProductConfigMapper erpAutoUnshelfProductConfigMapper;
    private final ErpAutoUnshelfProductLogMapper erpAutoUnshelfProductLogMapper;
    private final ErpAutoPulishProductProjectTaskMapper erpAutoPulishProductProjectTaskMapper;
    private final ErpAutoPulishProductProjectMapper erpAutoPulishProductProjectMapper;
    private final IErpAutoPublishProductProjectService autoPublishProductProjectService;
    @Resource
    private RemoteSellerStoreProductService remoteSellerStoreProductService;
    @Resource
    private RemoteOrderStatisticsService remoteOrderStatisticsService;
    @Resource
    private RemoteSellerStoreService remoteSellerStoreService;
    @Resource
    private RemoteSellerStoreCommodityRankStatisticsService remoteSellerStoreCommodityRankStatisticsService;
    @Resource
    private IErpAutoPulishProductProjectTaskService erpAutoPulishProductProjectTaskService;
    @Resource
    private RemoteGatherProductService remoteGatherProductService;

    @Override
    public Boolean saveUnShelfConfig(ErpAutoUnshelfProductConfig config) {
        Long id = config.getId();
        Date nowDate = new Date();
        if (id == null) {
            config.setCreateTime(nowDate);
            config.setUpdateTime(nowDate);
            return erpAutoUnshelfProductConfigMapper.insert(config) > 0;
        }
        config.setUpdateTime(nowDate);
        return erpAutoUnshelfProductConfigMapper.updateById(config) > 0;
    }

    @Override
    public List<ErpAutoUnshelfProductConfig> getList(ErpAutoUnshelfProductConfig config) {
        LambdaQueryWrapper<ErpAutoUnshelfProductConfig> queryWrapper = new LambdaQueryWrapper<>();
        if (config.getStoreId() != null)
            queryWrapper.eq(ErpAutoUnshelfProductConfig::getStoreId,config.getStoreId());
        if (config.getStatus() != null)
            queryWrapper.eq(ErpAutoUnshelfProductConfig::getStatus,config.getStatus());
        return erpAutoUnshelfProductConfigMapper.selectList(queryWrapper);
    }

    @Override
    public ErpAutoUnshelfProductConfig selectById(Long id) {
        return erpAutoUnshelfProductConfigMapper.selectById(id);
    }

    /**
     * 自动下架
     */
    public void autoUnShelfProductService(ErpAutoUnshelfProductConfig config) {
//        ErpAutoUnshelfProductConfig searchConfig = new ErpAutoUnshelfProductConfig();
//        searchConfig.setStatus(1);
//        List<ErpAutoUnshelfProductConfig> list = getList(searchConfig);
//        for (ErpAutoUnshelfProductConfig unshelfProductConfig : list) {
            unShelfAndShelf(config);
//        }
    }
    public void unShelfAndShelf(ErpAutoUnshelfProductConfig unshelfProductConfig) {
        // 执行下架操作
        Map<String, Integer> unShelfCountMap = autoUnShelfProduct(unshelfProductConfig);

        // 判断下架后是否上架
        int shelfNum = 0;// 上架数量
        Integer autoShelf = Integer.parseInt(unshelfProductConfig.getAutoShelf());
        // 有自动下架并且计划设定自动上架
        if (unShelfCountMap.get("code") == 200 && autoShelf != 0) {
            // 判断上架个数
            String isEqUnshelf = unshelfProductConfig.getIsEqUnshelf();
            if (isEqUnshelf != null) {
                if (isEqUnshelf.equals("1")) {
                    // 与下架数量相同，则根据下架数量调取上架计划
                    for (String key : unShelfCountMap.keySet()){
                        if(!key.equals("code")){
                            ErpAutoPulishProductProject productProject = erpAutoPulishProductProjectMapper
                                    .selectOne(new LambdaQueryWrapper<ErpAutoPulishProductProject>()
                                            .eq(ErpAutoPulishProductProject::getId, Long.parseLong(key)));
                            autoPublishProductProjectService.restartPulishProductProjectJob(productProject, unShelfCountMap.get(key), 2);
                        }
                    }
                } else {
                    // 指定下架数量，则平分计划数量
                    int projectCount = unShelfCountMap.size() - 1;
                    // 待上架数量
                    int waitOnlineCount = unshelfProductConfig.getShelfNum();
                    // 每个计划上架数量，向下取整
                    if (projectCount <= 0) {
                        return;
                    }
                    int onlineCountWithProject = (int) unshelfProductConfig.getShelfNum()/projectCount;
                    if (onlineCountWithProject == 0){
                        onlineCountWithProject = 1;
                    }
                    // 执行上架计划
                    for (String key : unShelfCountMap.keySet()){
                        if(!key.equals("code")){
                            ErpAutoPulishProductProject productProject = erpAutoPulishProductProjectMapper
                                    .selectOne(new LambdaQueryWrapper<ErpAutoPulishProductProject>()
                                            .eq(ErpAutoPulishProductProject::getId, Long.parseLong(key)));
                            autoPublishProductProjectService.restartPulishProductProjectJob(productProject, onlineCountWithProject, 2);
                            waitOnlineCount -= onlineCountWithProject;
                            if(waitOnlineCount == 0 || ((int) waitOnlineCount/onlineCountWithProject) < 2){
                                // 待上架数量为0或者待上架数量不足计划上架数量，或者待上架数量不足计划上架数量的两倍，全部上传
                                onlineCountWithProject = waitOnlineCount;
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 下架商品
     * @param config
     * @return
     */
    public Map<String, Integer> autoUnShelfProduct(ErpAutoUnshelfProductConfig config) {
        Map<String, Integer> offResult = new HashMap<>();
        List<ErpAutoUnshelfProductLog> logList = new ArrayList<>();
        ErpAutoUnshelfProductLog log = new ErpAutoUnshelfProductLog();
        Integer unshelf = 0;
        // 下架数量
        Integer unshelfNum = config.getUnshelfNum();
        if (unshelfNum != null) {
            unshelf = unshelfNum;
        }
        R<Object> storeEmpowerR = remoteSellerStoreService.getSellerStoreEmpowerByStoreId(config.getStoreId().toString());
        if (storeEmpowerR.getCode() != 200){
            log.setReason("该店铺无授权，或授权已过期");
            log.setStatus(0);
            log.setConfigId(config.getId());
            erpAutoUnshelfProductLogMapper.insert(log);
            offResult.put("code",500);
            return offResult;
        }
        if (config.getUnshelfPercentage() != null) {
            R<Object> sellerStoreProductR = remoteSellerStoreProductService.getProductCountByStoreId(config.getStoreId().toString());
            if (sellerStoreProductR.getCode() != 200 || Long.parseLong(sellerStoreProductR.getData().toString()) == 0){
                log.setReason("该店铺无在线商品，无法下架");
                log.setStatus(0);
                log.setConfigId(config.getId());
                erpAutoUnshelfProductLogMapper.insert(log);
                offResult.put("code",500);
                return offResult;
            }
            Long productVoSize = Long.parseLong(sellerStoreProductR.getData().toString());
            if (productVoSize != 0) {
                double expectSize = Double.parseDouble(config.getUnshelfPercentage().toString()) * productVoSize * 0.01;

                if (unshelf > expectSize) {
                    // 取小的
                    unshelf = (int) Math.floor(expectSize);
                }
            }
        }
        // 找前两天的订单
        LocalDate now = LocalDate.now();
        LocalDate minus = now.minus(Period.ofDays(2));
        // 找亏损的订单进行下架
        if (config.getLossPercentage() != null || config.getLossAmount() != null) {
            R<Object> childOrderStatisticsR = remoteOrderStatisticsService.getChildOrderStatisticsList(config.getStoreId().toString(), minus.toString(), now.toString());
            if(childOrderStatisticsR.getCode() != 200){
                log = new ErpAutoUnshelfProductLog();
                log.setReason("该店铺无统计数据，无法下架");
                log.setStatus(0);
                log.setConfigId(config.getId());
                erpAutoUnshelfProductLogMapper.insert(log);
                offResult.put("code",500);
                return offResult;
            }
            List<ErpChildOrderStatistics> lossList = JSONObject.parseArray(JSONObject.toJSONString(childOrderStatisticsR.getData()), ErpChildOrderStatistics.class);

            if (lossList != null) {
                for (ErpChildOrderStatistics childOrderStatistics : lossList) {
                    if (logList.size() == unshelf) {
                        break;
                    }
                    Long collectProductId = childOrderStatistics.getCollectProductId();
                    // 找到aeProductId
                    ErpSellerStoreProduct sellerStoreProduct = new ErpSellerStoreProduct();
                    sellerStoreProduct.setCollectProductId(collectProductId);
                    sellerStoreProduct.setStoreId(config.getStoreId());
                    sellerStoreProduct.setDelFlag("0");
                    R<Object> sellerStoreProductR = remoteSellerStoreProductService.getSellerStoreProductInfo(sellerStoreProduct);
                    if (sellerStoreProductR.getCode() != 200){
                        continue;
                    }
                    sellerStoreProduct = JSONObject.parseObject(JSONObject.toJSONString(sellerStoreProductR.getData()), ErpSellerStoreProduct.class);
                    if (sellerStoreProduct == null) {
                        continue;
                    }
                    String productProfit = childOrderStatistics.getProductProfit();
                    // 判断是否满足亏损条件
                    BigDecimal abs = new BigDecimal(productProfit).abs();
                    if (config.getLossAmount() != null) {
                        // 亏损金额是否大于lossAmount
                        if (abs.compareTo(new BigDecimal(config.getLossAmount())) > 0) {
                            log.setReason("亏损金额：" + abs + "，大于" + config.getLossAmount());
                            log.setStatus(0);
                            log.setProductId(sellerStoreProduct.getAeProductId());
                            log.setConfigId(config.getId());
                            logList.add(log);
                            continue;
                        }
                    }
                    if (config.getLossPercentage() != null) {
                        // 判断亏损率
                        BigDecimal lossRate = abs.divide(new BigDecimal(childOrderStatistics.getCostTotalPrice()), RoundingMode.HALF_EVEN);
                        if (lossRate.compareTo(new BigDecimal(config.getLossPercentage()).movePointLeft(2)) > 0) {
                            log.setReason("亏损率：" + lossRate + "，大于" + config.getLossPercentage());
                            log.setStatus(0);
                            log.setProductId(sellerStoreProduct.getAeProductId());
                            log.setConfigId(config.getId());
                            logList.add(log);
                        }
                    }
                }
            }
        }
        //1. 找到 近（cycle）天的商品
        // 根据storeId找到对应的cn，再根据cn码找到所有的storeId
        ErpSellerStoreEmpower storeEmpower = JSONObject.parseObject(JSONObject.toJSONString(storeEmpowerR.getData()), ErpSellerStoreEmpower.class);
        String storeUserName = storeEmpower.getStoreUserName();
        R<Object> storeEmpowerListR = remoteSellerStoreService.getStoreEmpowerListByCnCode(storeUserName);
        List<ErpSellerStoreEmpower> empowerList = JSONObject.parseArray(JSONObject.toJSONString(storeEmpowerListR.getData()), ErpSellerStoreEmpower.class);
        List<Long> storeIdList = empowerList.stream().map(ErpSellerStoreEmpower::getId).collect(Collectors.toList());
        R<Object> sellerStoreProductListR = remoteSellerStoreProductService.getProductByCycle(config.getCycle().toString(),
                String.join(",", StringUtils.convertLongArrayToStringArray(storeIdList.toArray(new Long[0]))));
        List<ErpSellerStoreProduct> productList = JSONObject.parseArray(JSONObject.toJSONString(sellerStoreProductListR.getData()), ErpSellerStoreProduct.class);
        if (productList == null || productList.size() == 0){
            log = new ErpAutoUnshelfProductLog();
            log.setReason("没有需要下架的商品");
            log.setStatus(0);
            log.setConfigId(config.getId());
            erpAutoUnshelfProductLogMapper.insert(log);
            offResult.put("code",500);
            return offResult;
        }
        for (ErpSellerStoreProduct sellerStoreProduct : productList) {
            if (logList.size() == unshelf) {
                break;
            }
            Long aeProductId = sellerStoreProduct.getAeProductId();
            // 判断是否有task
            Boolean taskByProductId = erpAutoPulishProductProjectTaskService.getTaskByProductId(aeProductId);
            if (!taskByProductId) {
                continue;
            }

            if (config.getHistory().equals("1")) {
                // 判断是否出过单，出单跳过
                boolean outOrder = remoteSellerStoreCommodityRankStatisticsService.isOutOrder(aeProductId);
                if (outOrder) {
                    continue;
                }
            }
            //2. 判断周期内的访客量
            Integer visitors = remoteSellerStoreCommodityRankStatisticsService
                    .getVisitorsTotalsByTime(aeProductId.toString(), config.getCycle().toString()).getData();
            if (visitors == null || visitors < config.getVisitorLess()) {
                log = new ErpAutoUnshelfProductLog();
                log.setReason("访客量小于" + config.getVisitorLess());
                log.setStatus(0);
                log.setProductId(sellerStoreProduct.getAeProductId());
                log.setConfigId(config.getId());
                logList.add(log);
            }
        }
        int lossSize = logList.size();
        if (lossSize == 0){
            log = new ErpAutoUnshelfProductLog();
            log.setReason("没有符合条件的下架商品");
            log.setStatus(0);
            log.setConfigId(config.getId());
            erpAutoUnshelfProductLogMapper.insert(log);
            offResult.put("code",500);
            return offResult;
        }


        for (ErpAutoUnshelfProductLog productLog : logList) {
            Long productId = productLog.getProductId();
            R<Object> stringR =  remoteGatherProductService.productOfflineOrOnline(productId.toString(), config.getStoreId().toString(), "0");

            if (stringR.getCode() == 200) {
                // 下架成功
                productLog.setStatus(1);
                // 记录该商品上架时的projectId
                ErpAutoPulishProductProjectTask productProjectTask = erpAutoPulishProductProjectTaskMapper
                        .selectOne(new LambdaQueryWrapper<ErpAutoPulishProductProjectTask>()
                                .eq(ErpAutoPulishProductProjectTask::getAeProductId, productLog.getProductId()));
                if (productProjectTask == null) {
                    // 新的表没有去老的表找erp_auto_pulish_product_project_task_old
                    productProjectTask = erpAutoPulishProductProjectTaskMapper.selectOneOld(productLog.getProductId());
                }
                if (productProjectTask == null)
                    continue;
                // 记录projectId对应的下架个数
                if(offResult.containsKey(productProjectTask.getProjectId().toString())){
                    // 包含该计划
                    offResult.put(productProjectTask.getProjectId().toString(), (offResult.get(productProjectTask.getProjectId().toString())+1));
                }else {
                    offResult.put(productProjectTask.getProjectId().toString(), 1);
                }
            }else {
                productLog.setStatus(2);
                productLog.setRemark(JSONObject.toJSONString(stringR.getData()));
            }
            productLog.setCreateTime(DateUtils.getTime());
            erpAutoUnshelfProductLogMapper.insert(productLog);
        }

        offResult.put("code",200);
        return offResult;
    }

}
